/**
 *
 */
package ua.at.tsvetkov.samizdat.data;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import ua.at.tsvetkov.net.NetCheck;
import ua.at.tsvetkov.strings.Util;
import ua.at.tsvetkov.ui.ProgressManager;
import ua.at.tsvetkov.ui.Rout;
import ua.at.tsvetkov.util.Log;
import android.app.ProgressDialog;
import android.widget.Toast;

import ua.at.tsvetkov.samizdat.Const;
import ua.at.tsvetkov.samizdat.R;
import ua.at.tsvetkov.samizdat.activities.AcTemplate;

/**
 * Класс читающий книгу по строке запроса.
 * 
 * @author A.Tsvetkov 2011, http://tsvetkov.at.ua, al@ukr.net
 */
public class AllBooksDownloader {

	public static final boolean		TEXT									= true;
	public static final boolean		DATA									= false;
	public static final boolean		FORSED_LOADING_FROM_SD			= true;
	public static final boolean		FORSED_LOADING_FROM_INTERNET	= false;
	private static final String		ENCODING								= "windows-1251"; // "koi8-r";
	private static final String		CR										= "\n";

	private ProgressManager				pm;
	private String							urlStr;
	private AcTemplate					context;
	private OnCompleteLoadListener	onCompleteLoadListener;
	private String							header;
	private ArrayList<String>			booksData;
	private ProgressDialog				progress;

	/**
	 * Инициализирует класс загрузки данных.
	 * 
	 * @param context текущий контекст
	 * @param urlStr строка для загрузки в интернете
	 * @param size размер в килобайтах
	 */
	public AllBooksDownloader(AcTemplate context, ProgressDialog progress, String urlStr) {
		this.context = context;
		this.urlStr = urlStr;
		this.progress = progress;
	}

	/**
	 * Назначает обработчик окончания загрузки
	 * 
	 * @param onCompleteLoadListener
	 */
	public void setOnCompleteLoadListener(OnCompleteLoadListener onCompleteLoadListener) {
		this.onCompleteLoadListener = onCompleteLoadListener;
	}

	/**
	 * Загрузка данных из интернета на карту.
	 * 
	 * @param fileName имя файла для записи
	 * @param clean производить очистку строк от мусора
	 * @param reload производить обязательную перезагрузку из интернета
	 */
	public void download() {
		booksData = new ArrayList<String>();
		Log.v("Try download url=" + urlStr);
		getBookData();
		pm = new ProgressManager(context, progress, context.getString(R.string.loading_from_internet), booksData.size(), booksData.size());
		new Thread(new Runnable() {

			@Override
			public void run() {
				if (NetCheck.getInstance().isOnline() && urlStr != null && urlStr.length() > 0) {
					boolean result = true;
					for (int i = 0; i < booksData.size(); i++) {
						String[] data = booksData.get(i).split("\\|");
						for (int j = 0; j < data.length; j++) {
							data[j] = data[j].trim();
						}
						String fileName = data[Data.BOOK_TITLE].replace(":", "").replace("?", "").replace("*", "");
						String path = Const.PATH_BOOKS + data[Data.BOOK_AUTHOR] + File.separator;
						(new File(path)).mkdirs();
						pm.setTitle("Загружается " + fileName);
						fileName = path + fileName + ".txt";
						String url = Const.URL_BOOK + data[Data.BOOK_OBJECT];
						result = loadBookAndSave(fileName, url);
						pm.increment(1);
						if (!result) {
							Rout.toast(context, NetCheck.getInstance().getStatusStringRu(), Toast.LENGTH_LONG);
							break;
						}
					}
					pm.remove();
					onCompleteLoadListener.loadComplete(result);
				} else {
					Rout.toast(context, NetCheck.getInstance().getStatusStringRu(), Toast.LENGTH_LONG);
				}
			}
		}).start();
	}

	/**
	 * Загрузка данных книг из интернета.
	 * 
	 * @param fileName
	 * @param clean
	 * @param reload
	 */
	private boolean getBookData() {
		BufferedReader in = null;
		InputStream is = null;
		InputStreamReader br = null;
		try {
			HttpURLConnection connection;
			URL url = new URL(urlStr);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(Const.TIMEOUT);
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
			connection.setRequestProperty("User-Agent", "Android reader");
			is = connection.getInputStream();
			br = new InputStreamReader(is, ENCODING);
			in = new BufferedReader(br);
			String st = "";
			while (true) {
				st = in.readLine();
				if (st != null) {
					if (st.trim().length() != 0) {
						booksData.add(st);
					}
				} else {
					break;
				}
			}
			in.close();
			br.close();
			is.close();
			Log.v("Loaded and saved " + urlStr);
		} catch (Exception e) {
			Log.e("Failed loading " + urlStr, e);
			return false;
		}
		return true;
	}

	/**
	 * Загрузка книги из интернета.
	 * 
	 * @param fileName
	 * @param urlStr
	 */
	private boolean loadBookAndSave(String fileName, String urlStr) {
		File file = new File(fileName);
		boolean isOld = System.currentTimeMillis() - file.lastModified() > Const.LIVE_TIME;
		if (file.exists() && (isOld)) {
			return true;
		}
		BufferedReader in = null;
		InputStream is = null;
		InputStreamReader br = null;
		BufferedWriter out = null;
		try {
			HttpURLConnection connection;
			URL url = new URL(urlStr);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(Const.TIMEOUT);
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
			connection.setRequestProperty("User-Agent", "Android reader");
			is = connection.getInputStream();
			br = new InputStreamReader(is, ENCODING);
			in = new BufferedReader(br);
			out = new BufferedWriter(new FileWriter(file));
			String st = in.readLine();
			String stOld = st;
			// Очистка строки заголовка
			header = st;
			String[] sts = header.split("\\|");
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < sts.length; i++) {
				sts[i] = sts[i].trim();
				if (sts[i].length() == 0) {
					sts[i] = " ";
				}
				if (i == Data.HEADER_TITLE) {
					sts[i].replace(":", "").replace("?", "").replace("*", "");
				}
				sb.append(sts[i] + '|');
			}
			header = sb.toString() + urlStr;
			out.write(header + CR); // Запись заголовка
			while (true) {
				st = in.readLine();
				if (st == null)
					break;
				st = Util.removeHtmlTag(st.trim());
				if (!(st.trim().length() == 0 && stOld.trim().length() == 0)) {
					out.write(st.trim() + CR);
				}
				stOld = st;
			}
			in.close();
			br.close();
			is.close();
			out.flush();
			out.close();
			Log.v("Loaded and saved " + urlStr);
		} catch (Exception e) {
			Log.e("Failed loading " + urlStr, e);
			return false;
		}
		return true;
	}
}
